#!/bin/bash

##########################################
# default parameter

# "by-id" or "by-path" is possible 
# 	id 		= same device (model and revision match) gets same device-name
#	path	= device at port X gets same device-name
CD_RULES_MODE="by-id"

##########################################

LOG_ERRORS=""

echo "Setup ethernet card names..."
RESULT=$(bash /lib/udev/init-net-rules.sh)
if (($? != 0)); then
	LOG_ERRORS+="--|Setup ethernet card names...|----------"$'\n';
	LOG_ERRORS+="$RESULT"$'\n';
fi

echo "Set CD-Drive naming rules" && \
eval "sed -i -e 's/\"write_cd_rules.*\"/\"write_cd_rules $CD_RULES_MODE\"/' /etc/udev/rules.d/83-cdrom-symlinks.rules"

if (($? != 0)); then
	echo "Aborted";
	exit 1;
fi

LIST_DEVS="tty
hwmon
mem
i2c-adapter
leds
mmc_host
pci_bus
power_supply
powercap
pwm
regulator
rtc
spi_host
spi_master
spi_transport
thermal
watchdog
hidraw
backlight
block
net
input
bluetooth
graphics
sound
printer
video4linux
"

echo "" > ./installed_hw.log

echo "List hardware..."
for hwclass in $LIST_DEVS; do
	HW_CLASS=$(echo "$hwclass" | tr [:lower:] [:upper:]);
	echo "--|$HW_CLASS|--------------------------------------------------------------------------" | cut -c1-80 >> ./installed_hw.log;
	for hw in /sys/class/$hwclass/*; do
		if [[ $hw != *"/*" ]]; then
			HW_INFO=$(udevadm info -a -p $hw 2> /dev/null | grep 'looking at \|KERNEL==\|DRIVER\|ATTRS{name}==\|ATTRS{phys}==\|ATTRS{idVendor}==\|ATTRS{idProduct}==\|ATTRS{vendor}==\|ATTRS{device}==');
			if [[ $hw != *"loop"* && $hw != *"ram"* ]]; then
				echo "-->|$hw|------------------------------------------------------------------------" | cut -c1-80 >> ./installed_hw.log;
				echo "$HW_INFO" >> ./installed_hw.log;
			fi
		fi
	done
	echo "" >> ./installed_hw.log;
done

echo "Create example dupilcate device rules...";
if [ -r /etc/udev/rules.d/83-duplicate_devs.rules ]; then
	echo "/etc/udev/rules.d/83-duplicate_devs.rules already exists, don't touch it";
else
	echo "Add rules for stable device links (e.g. /dev/webcam, /dev/tvtuner) into /etc/udev/rules.d/83-duplicate_devs.rules, example rules are added.";
	echo '# Persistent symlinks for webcam and tuner
#KERNEL=="video*", ATTRS{idProduct}==\"1910\", ATTRS{idVendor}=="0d81", \
    SYMLINK+="webcam"
#KERNEL=="video*", ATTRS{device}=="0x036f", ATTRS{vendor}=="0x109e", \
    SYMLINK+="tvtuner"
' > /etc/udev/rules.d/83-duplicate_devs.rules;
	if (($? != 0)); then
		echo "Aborted";
		exit 1;
	fi
fi

echo "Setup network interfaces... default: DHCP";
for net in $(ls /sys/class/net); do
	if [ -r /sys/class/net/$net ]; then
		echo " Interface: $net";
		HW_INFO=$(udevadm info -a -p /sys/class/net/$net 2> /dev/null);
		if [[ $(echo "$HW_INFO" | grep '/virtual/') != "" ]]; then
			echo "  --> ignore virtual interfaces";
		else
			MACADDR=$(echo "$HW_INFO" | grep 'ATTR{address}==' | sed 's/[^"]*"\([^"]*\).*/\1/');
			echo "  --> check for MAC address: $MACADDR";
			MAC_HEX=$(echo "$MACADDR" | tr -d ':');
			if [[ $MAC_HEX == '00:00:00:00:00:00' ]]; then
				echo "Invalid MAC address, ignore interface";
			else
				if [ -r /etc/sysconfig/ifconfig.$net ]; then
					echo "Configuration /etc/sysconfig/ifconfig.$net already exists, don't touch it";
				else
					echo "Write configuration to /etc/sysconfig/ifconfig.$net";
					echo "ONBOOT=\"yes\"
IFACE=\"$net\"
SERVICE=\"dhclient\"
DHCP_START=\"\"
DHCP_STOP=\"\"

# Set PRINTIP=\"yes\" to have the script print
# the DHCP assigned IP address
PRINTIP=\"yes\"

# Set PRINTALL=\"yes\" to print the DHCP assigned values for
# IP, SM, DG, and 1st NS. This requires PRINTIP=\"yes\".
PRINTALL=\"yes\"
" > /etc/sysconfig/ifconfig.$net;
					if (($? != 0)); then
						echo "Aborted";
						exit 1;
					fi
				fi
			fi
		fi
	fi
done

echo "Writing pattern resolv.conf file"
if [ -r /etc/resolv.conf ]; then
	echo "Configuration /etc/resolv.conf already exists, don't touch it";
else
	echo '# Begin /etc/resolv.conf

#domain <Your Domain Name>
#nameserver <IP address of your primary nameserver>
#nameserver <IP address of your secondary nameserver>

# End /etc/resolv.conf' > /etc/resolv.conf;
fi

echo "Writing pattern hostname file"
if [ -r /etc/hostname ]; then
	echo "Configuration /etc/hostname already exists, don't touch it";
else
	echo 'lfs' > /etc/hostname;
fi

echo "Writing pattern hosts file"
if [ -r /etc/hosts ]; then
	echo "Configuration /etc/hosts already exists, don't touch it";
else
	echo '# Begin /etc/hosts

127.0.0.1 lfs.example.org> lfs localhost
#<192.168.1.1> <HOSTNAME.example.org> [alias1] [alias2 ...]

# End /etc/hosts (no network card version)' > /etc/hosts;
fi


echo "Writing pattern inittab file"
if [ -r /etc/inittab ]; then
	echo "Configuration /etc/inittab already exists, don't touch it";
else
	echo '# Begin /etc/inittab

id:3:initdefault:

si::sysinit:/etc/rc.d/init.d/rc S

l0:0:wait:/etc/rc.d/init.d/rc 0
l1:S1:wait:/etc/rc.d/init.d/rc 1
l2:2:wait:/etc/rc.d/init.d/rc 2
l3:3:wait:/etc/rc.d/init.d/rc 3
l4:4:wait:/etc/rc.d/init.d/rc 4
l5:5:wait:/etc/rc.d/init.d/rc 5
l6:6:wait:/etc/rc.d/init.d/rc 6

ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

su:S016:once:/sbin/sulogin

1:2345:respawn:/sbin/agetty --noclear tty1 9600
2:2345:respawn:/sbin/agetty tty2 9600
3:2345:respawn:/sbin/agetty tty3 9600
4:2345:respawn:/sbin/agetty tty4 9600
5:2345:respawn:/sbin/agetty tty5 9600
6:2345:respawn:/sbin/agetty tty6 9600

# End /etc/inittab' > /etc/inittab;
fi


echo "Writing pattern clock file"
if [ -r /etc/sysconfig/clock ]; then
	echo "Configuration /etc/sysconfig/clock already exists, don't touch it";
else
	echo '# Begin /etc/sysconfig/clock

UTC=1

# Set this to any options you might need to give to hwclock,
# such as machine hardware clock type for Alphas.
CLOCKPARAMS=

# End /etc/sysconfig/clock' > /etc/sysconfig/clock;
fi


echo "Writing pattern console file"
if [ -r /etc/sysconfig/console ]; then
	echo "Configuration /etc/sysconfig/console already exists, don't touch it";
else
	echo '# Begin /etc/sysconfig/console

UNICODE="1"
KEYMAP="de-latin1"
KEYMAP_CORRECTIONS="euro2"
LEGACY_CHARSET="iso-8859-15"
FONT="LatArCyrHeb-16 -m 8859-15"

# End /etc/sysconfig/console' > /etc/sysconfig/console;
fi


echo "Writing pattern inputrc file"
if [ -r /etc/inputrc ]; then
	echo "Configuration /etc/inputrc already exists, don't touch it";
else
	echo '# Begin /etc/inputrc
# Modified by Chris Lynn <roryo@roryo.dynup.net>

# Allow the command prompt to wrap to the next line
set horizontal-scroll-mode Off

# Enable 8bit input
set meta-flag On
set input-meta On

# Turns off 8th bit stripping
set convert-meta Off

# Keep the 8th bit for display
set output-meta On

# none, visible or audible
set bell-style none

# All of the following map the escape sequence of the value
# contained in the 1st argument to the readline specific functions
"\eOd": backward-word
"\eOc": forward-word

# for linux console
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert

# for xterm
"\eOH": beginning-of-line
"\eOF": end-of-line

# for Konsole
"\e[H": beginning-of-line
"\e[F": end-of-line

# End /etc/inputrc' > /etc/inputrc;
fi



echo "Writing pattern fstab file"
if [ -r /etc/fstab ]; then
	echo "Configuration /etc/fstab already exists, don't touch it";
else

	DF_RESULT="$(mount -l | grep '/dev/' | tr [:blank:] ';')";
	if (( $? != 0 )); then
		echo "Failed to probe disk mount state with command 'mount -l'...";
		exit 3;
	fi
	
	echo '# Begin /etc/fstab

# file system  mount-point  type     options             dump  fsck
#                                                              order
' > /etc/fstab

	for fsdev in $DF_RESULT; do
		echo "Processing: $fsdev"
		fsinfo=(`echo "$fsdev" | tr ';' '\n'`);
		if (( ${#fsinfo[@]} < 5 )); then
			echo "Wrong output format of command 'mount -l', expecting in min. 5 columns, but only ${#fsinfo[@]} parsed in line $fsdev";
			exit 4;
		fi
		echo "${fsinfo[0]}     ${fsinfo[2]}     ${fsinfo[4]}  defaults  1  1" >> /etc/fstab;
	done
	
	echo 'proc           /proc        proc     nosuid,noexec,nodev 0     0
sysfs          /sys         sysfs    nosuid,noexec,nodev 0     0
devpts         /dev/pts     devpts   gid=5,mode=620      0     0
tmpfs          /run         tmpfs    defaults            0     0
devtmpfs       /dev         devtmpfs mode=0755,nosuid    0     0

# End /etc/fstab
' >> /etc/fstab;
fi


echo "Writing grub configuration"
mkdir -pv /boot/grub || exit $?
DF_RESULT="$(mount -l | grep '/dev/' | tr [:blank:] ';')";
SYS_DEVICE="";
GRUB_DEVICE="";
if (( $? != 0 )); then
	echo "Failed to probe disk mount state with command 'mount -l'...";
	exit 5;
fi
CHAR_A=$(printf '%d' "'a");
for fsdev in $DF_RESULT; do
	echo "Processing: $fsdev"
	fsinfo=(`echo "$fsdev" | tr ';' '\n'`);
	if (( ${#fsinfo[@]} < 5 )); then
		echo "Wrong output format of command 'mount -l', expecting 5 columns in min., but only ${#fsinfo[@]} parsed in line $fsdev";
		exit 6;
	fi
	if [[ ${fsinfo[2]} == "/" ]]; then
		# found system root
		echo "Found ${fsinfo[2]} on device ${fsinfo[0]}";
		SYS_DEVICE=${fsinfo[0]};
		
	elif [[ ${fsinfo[2]} == "/boot" ]]; then
		# found grub root
		echo "Found ${fsinfo[2]} on device ${fsinfo[0]}";
		GRUB_DEVICE=${fsinfo[0]};
	fi
done


GRUB_HD="";
if [[ $SYS_DEVICE != "" ]]; then
	if [[ $GRUB_DEVICE == "" ]]; then
		GRUB_DEVICE=$SYS_DEVICE;
	fi
	HDD_INFO=$(echo $GRUB_DEVICE | sed 's/^\/dev\/[sh]d\([a-z]\)\([1-9]\)/\1:\2/g');
	echo "HDD_INFO = $HDD_INFO";
	if [[ $HDD_INFO == $GRUB_DEVICE || $HDD_INFO == "" ]]; then
		echo "Stop probe, device literal dosn't match the expected form /dev/hd[a-z][1-9] nor /dev/sd[a-z][1-9]";
		exit 7;
	fi
	# number of the drive
	DRIVENO=$(echo $HDD_INFO | cut -d: -f1);
	DRIVENO=$(printf "%d" "'$DRIVENO");
	DRIVENO=$((DRIVENO-CHAR_A));
	# number of the partition
	PARTNO=$(echo $HDD_INFO | cut -d: -f2);
	# check numbers
	if (( DRIVENO >= 0 || DRIVENO <= 9 )); then
		if (( PARTNO >= 1 || PARTNO <= 9 )); then
			GRUB_HD="hd$DRIVENO,$PARTNO";
		else
			echo "Wrong partition number parsed: $PARTNO";
		fi
	else
		echo "Wrong drive number parsed: $DRIVENO";
	fi
	
else
	echo "No system device found";
	exit 8;
fi

# check HD parameter
if [[ $GRUB_HD == "" ]]; then
	echo "Abort grub configuration, couldn't find bootable partition...";
	exit 9;
fi

# write grub configuration
GRUBCFG=""
if [ -r /boot/grub/grub.cfg ]; then
	echo "Configuration /boot/grub/grub.cfg already exists, backup it";
	cp -av /boot/grub/grub.cfg /boot/grub/grub.cfg_$(date +%F_%T) && \
	GRUBCFG="$(cat /boot/grub/grub.cfg)";
	if (( $? != 0 )); then
		echo "Aborted";
		exit 10;
	fi
else
	GRUBCFG="# Begin /boot/grub/grub.cfg
set default=0
set timeout=5

insmod ext2
";
fi

# get all bootable kernels
for bs in /boot/vmlinuz-*; do
	echo "Found linux image $bs";
	LINUX_IMG=$(echo $bs | tr -d '/boot/');
	LINUX=$(echo $LINUX_IMG | tr -d 'vmlinuz-');
	if [[ $(echo "$GRUBCFG" | grep $LINUX_IMG) != "" ]]; then
		echo "Image $LINUX_IMG already in grub menu, ignore it";
	else
		if [[ $SYS_DEVICE == $GRUB_DEVICE ]]; then
			GRUB_ROOT="/boot/";
		else
			GRUB_ROOT="/";
		fi
		# append menu entry
		GRUBCFG="$GRUBCFG

set root=($GRUB_HD)
menuentry \"GNU/Linux, Linux $LINUX\" {
        linux $GRUB_ROOT$LINUX_IMG root=$SYS_DEVICE ro
}
";
	fi
done

echo "$GRUBCFG" > /boot/grub/grub.cfg


if [ ! -d /etc/skel ]; then
	echo "Create skel settings";
	mkdir -pv /etc/skel && \
	cp -vf /sources/defaults/etc/skel/* /etc/skel/ && \
	chmod 700 -R /etc/skel || exit 10;
fi

if [ ! -d /etc/profile.d ]; then
	install --directory --mode=0755 --owner=root --group=root /etc/profile.d;
	cp -vf /sources/defaults/etc/profile.d/* /etc/profile.d/;
fi

./set_locale.sh
if (( $? != 0 )); then
	echo "Abort on locale settings";
	exit 2;
fi

if [ ! -e /etc/profile ]; then
	cp -vf /sources/defaults/etc/profile /etc/
fi

if [ ! -e /etc/dircolors ]; then
	cp -vf /sources/defaults/etc/dircolors /etc/
fi

if [ ! -e /etc/issue ]; then
	clear > /etc/issue;
	echo 'Welcome to \s on \l!
Tody is \d \t - \u user(s) logged in.

Running on: \m (OS version \v, kernel \r)
' >> /etc/issue;
fi

if [ ! -e /etc/shells ]; then
	echo "# Begin /etc/shells

/bin/sh
/bin/bash

# End /etc/shells" > /etc/shells;
fi

echo "7.6" > /etc/lfs-release;
echo "DISTRIB_ID=\"Linux From Scratch\"
DISTRIB_RELEASE=\"7.6\"
DISTRIB_CODENAME=\"$(cat /sources/distname | tr -d '[:space:]')\"
DISTRIB_DESCRIPTION=\"Based on Linux From Scratch 7.6\"" > /etc/lsb-release


echo ""
echo "Finished set up..."
echo "Detected hardware is listed in ./installed_hw.log"
echo ""
echo "To install grub into MBR run: grub-install $(echo $GRUB_DEVICE | sed 's|^/dev/\([sh]\)d\([a-z]\)[1-9]|/dev/\1d\2|')"
echo ""

if [[ $LOG_ERRORS != "" ]]; then
	echo "But some errors logged... please check the following messages if there were something important went wrong:";
	echo "$LOG_ERRORS";
	echo ""
fi



